/***********************************************************
 * Test Program: primary part
 * @Author: Kevinx
 *
 *
 ***********************************************************/
#include "fdt_channel.h"
#include "fdt_shmmgr.h"
#include "fdt_config.h"
#include <unistd.h>
#include <string.h>
#include <stdio.h>

static int fdt_callback_func(struct fdt_channel* c)
{
    int nbytes;
    int i;
    struct fdt_buffer buffer[10];

    memset(&buffer, 0, COUNT_TO_BYTES(10));

    nbytes = fdt_channel_receive(c, buffer, COUNT_TO_BYTES(10));

    //.....

    return 0;
}

static struct fdt_callback fdt_callback = {
    fdt_callback_func
}

int main()
{
    struct fdt_channel mch;

    make_primary_MSG_channel(&mch);
    
    struct cid_t id1 = MKCID("FDT", NULL, 0);
    fdt_channel_open(&mch, &id1, 0);

    const char* msg = "hello, buddy!";
    fdt_channel_send(&mch, msg, strlen(msg)+1);

    char buf[128] = {0};
    
    if (fdt_channel_poll(&mch, NULL) > 0) {
        fdt_channel_receive(&mch, buf, 128);

        printf("ulayer recv: %s\n", buf);
    }

    fdt_channel_close(&mch);

    struct fdt_shmmgr shmmgr;

    if (fdt_shmmgr_create(&shmmgr, "ulayer", MEGABYTES(64)) == -1) {
        printf("ulayer: shmmgr create failed.\n");
        return 0;
    }

    struct fdt_channel pch;
    make_primary_PTR_channel(&pch, &shmmgr);

    struct cid_t id = MKCID("FDT", "llayer", 64);
    if (fdt_channel_open(&pch, &id, 0) == -1) {
        printf("ulayer: channel open falile.\n");
        return 0;
    }

    struct fdt_buffer buffer;
    buffer.packet_ptr.ptr = fdt_shmmgr_alloc(&shmmgr);

    const char* str = "The strlen() function calculates the length of the string s, not including the terminating \'\\0\' character.";
    buffer.len = strlen(str) + 1;
    memcpy(buffer.packet_ptr.ptr, str, buffer.len);

    fdt_channel_send(&pch, &buffer, sizeof(buffer));

    if (fdt_PTRch_GC_poll(&pch, NULL) > 0) {
        fdt_PTRch_gcollect(&pch);
        printf("ulayer: garbage collected.\n");
    }
    
    struct fdt_daemon fdt_daemon;
    fdt_daemon_init(&fdt_daemon);

    fdt_daemon_add_channel(&fdt_daemon, &pch, &fdt_callback);

    //fdt_channel_close(&pch);

    //fdt_shmmgr_destory(&shmmgr);

    return 0;
}
